#include "Base64.h"
#include "ap_base64.h"
#include "ia.h"

std::string Base64::Encode(unsigned char* pData, int bytesToEncode)
{
	int encodeLen = base64encode_len(bytesToEncode);
	
	char* pBufferEncoded = (char*)malloc(encodeLen);
	if (NULL == pBufferEncoded) {
		return std::string();
	}
	memset(pBufferEncoded, 0, encodeLen);

	int successLen = ap_base64encode_binary(pBufferEncoded, pData, bytesToEncode);
	if (successLen != encodeLen) {
		return std::string();
	}

	std::string resultStr = std::string(pBufferEncoded);

	IA_FREE(pBufferEncoded);
	return resultStr;
}

int Base64::GetDecodeLen(std::string base64Str)
{
	return ap_base64decode_len(&base64Str[0]);
}

int Base64::Decode(std::string base64Str, unsigned char* pBuffer, int bufferSize)
{
	IA_ASSERT(pBuffer != NULL && bufferSize > 0);

	memset(pBuffer, 0, bufferSize);

	int bytesToDecode = base64decode_len(&base64Str[0]);
	// bytesToDecode > bufferSize ~3
	//IA_ASSERT(bufferSize >= bytesToDecode);

	int realBytes = base64decode_binary(pBuffer, &base64Str[0]);
	//IA_ASSERT(realBytes == bytesToDecode);
	// bytesToDecode -realBytes >=2
	IA_ASSERT(bufferSize==1 || realBytes > 0);

	IA_RETURN_OK
}

std::string Base64::Decode(std::string base64Str)
{
	std::string resultStr;
	int len = base64decode_len(&base64Str[0]);

	char* pData = (char*)malloc(len);
	if (NULL == pData) {
		return resultStr;
	}
	memset(pData, 0, len);
	
	int status = Decode(base64Str, (unsigned char*)pData, len);
	if (status != IA_L_OK) {
		IA_FREE(pData);
		return resultStr;
	}
	resultStr = std::string(pData);

	IA_FREE(pData);
	return resultStr;
}

int Base64::base64decode_len(const char* bufcoded)
{
	return ap_base64decode_len(bufcoded);
}

int Base64::base64decode(char* bufplain, const char* bufcoded)
{
	return ap_base64decode(bufplain, bufcoded);
}

int Base64::base64decode_binary(unsigned char* bufplain, const char* bufcoded)
{
	return ap_base64decode_binary(bufplain, bufcoded);
}

int Base64::base64encode_len(int len)
{
	return ap_base64encode_len(len);
}

int Base64::base64encode(char* encoded, const char* string, int len)
{
	return  ap_base64encode(encoded, string, len);
}

int Base64::base64encode_binary(char* encoded, const unsigned char* string, int len)
{
	return ap_base64encode_binary(encoded, string, len);
}
